﻿namespace Yom.Template
{
    using System.Collections.Generic;
    using System.Text;
    using System.Web;
    using Yom.Common;
    using Yom.Template.Model;

    public static class SkinTheme
    {
        private static readonly Dictionary<string, int> _BlockCache = new Dictionary<string, int>();
        private static readonly Dictionary<string, SkinTree<SkinNode>> _Cache = new Dictionary<string, SkinTree<SkinNode>>();
        private static readonly Dictionary<string, bool> _ElectCache = new Dictionary<string, bool>();
        private static readonly Dictionary<string, string> _LabelCache = new Dictionary<string, string>();
        private static string _SkinName;
        public static string PostSkin = string.Empty;

        public static void ClearCache()
        {
            _BlockCache.Clear();
            _Cache.Clear();
            _ElectCache.Clear();
            _LabelCache.Clear();
        }

        private static bool GetCon(string strVal)
        {
            bool flag = false;

            if (string.IsNullOrEmpty(strVal))
                return flag;

            bool flag2 = false;

            if (strVal[0] == '!')
            {
                flag2 = true;
                strVal = strVal.TrimStart(new char[] { '!' });
            }

            _ElectCache.TryGetValue(strVal, out flag);

            return (flag2 ? !flag : flag);
        }

        private static string GetLan(string strVal)
        {
            string str = string.Empty;

            if (!string.IsNullOrEmpty(strVal))
                str = SiteLoad.GetLan(strVal);

            return str;
        }

        private static SkinTree<SkinNode> GetSkinTree(string strFileName)
        {
            if (!_Cache.ContainsKey(strFileName))
            {
                SkinTree<SkinNode> tree = new SkinExec().Parse(_SkinName, strFileName);
                _Cache.Add(strFileName, tree);

                return tree;
            }

            return _Cache[strFileName];
        }

        private static int GetTbl(string strVal)
        {
            int num = 0;

            if (!string.IsNullOrEmpty(strVal))
                _BlockCache.TryGetValue(strVal, out num);

            return num;
        }

        private static int GetTbl(string strText, List<SkinData> sList)
        {
            foreach (SkinData data in sList)
            {
                if (data.Table.Equals(strText.TrimStart(new char[] { '!' })))
                    return data.Index;
            }

            return -1;
        }

        private static string GetVar(string strVal)
        {
            if (!string.IsNullOrEmpty(strVal))
                _LabelCache.TryGetValue(strVal, out strVal);

            return strVal;
        }

        public static string RunParse(string strFileName)
        {
            string strContent = RunParse(GetSkinTree(strFileName), null, strFileName);
            _LabelCache.Clear();
            _BlockCache.Clear();
            _ElectCache.Clear();

            return strContent;
        }

        private static string RunParse(SkinTreeNode<SkinNode> oTree, List<SkinData> cTable, string strFileName)
        {
            if (cTable == null)
                cTable = new List<SkinData>();

            bool flag = false;
            int num = 1;

            if (oTree.Content is TblSkinNode)
            {
                flag = cTable.Count > 0;
                num = flag ? cTable[cTable.Count - 1].Count : 1;

                if (string.IsNullOrEmpty(PostSkin))
                {
                    StringBuilder builder = new StringBuilder();

                    foreach (SkinTreeNode<SkinNode> node in oTree.Childs)
                    {
                        if (node.Content is ConSkinNode)
                        {
                            foreach (SkinTreeNode<SkinNode> node2 in node.Childs)
                            {
                                if (node2.Content is VarSkinNode)
                                {
                                    builder.Append("{");
                                    builder.Append(node2.Content.Value);
                                    builder.Append("}");
                                }
                                else if (!(node2.Content is ConSkinNode))
                                    builder.Append(node2.Content.Value);
                            }
                            continue;
                        }

                        if (node.Content is VarSkinNode)
                        {
                            builder.Append("{");
                            builder.Append(node.Content.Value);
                            builder.Append("}");
                        }
                        else if (!(node.Content is ConSkinNode))
                            builder.Append(node.Content.Value);
                    }

                    PostSkin = builder.ToString();
                }
            }

            StringBuilder strContent = new StringBuilder();

            for (int i = 0; i < num; i++)
            {
                if (flag)
                    cTable[cTable.Count - 1].Index = i;

                foreach (SkinTreeNode<SkinNode> node4 in oTree.Childs)
                {
                    int num2;
                    SkinNode content = node4.Content;

                    if (content is TxtSkinNode)
                    {
                        strContent.Append(content.Value);
                        continue;
                    }

                    if (content is LanSkinNode)
                    {
                        strContent.Append(GetLan(content.Value));
                        continue;
                    }

                    if (content is TblSkinNode)
                    {
                        string str = content.Value;

                        if (str.IndexOf('.') > 0)
                        {
                            num2 = GetTbl(str.Split(new char[] { '.' })[0], cTable);
                            if (num2 != -1)
                            {
                                str = string.Format("{0}_{1}", str, num2);
                            }
                        }

                        int tbl = GetTbl(str);
                        if (tbl != 0)
                        {
                            cTable.Add(new SkinData(content.Value, tbl, -1));
                            strContent.Append(RunParse(node4, cTable, strFileName));
                        }
                        continue;
                    }

                    if (content is ConSkinNode)
                    {
                        string str = content.Value;

                        if (str.IndexOf('.') > 0)
                        {
                            num2 = GetTbl(str.Split(new char[] { '.' })[0], cTable);

                            if (num2 != -1)
                                str = string.Format("{0}_{1}", str, num2);
                        }

                        if (GetCon(str))
                            strContent.Append((RunParse(node4, cTable, strFileName)));

                        continue;
                    }

                    if (content is VarSkinNode)
                    {
                        string str2 = content.Value;

                        if (str2.IndexOf('.') > 0)
                        {
                            num2 = GetTbl(str2.Split(new char[] { '.' })[0], cTable);

                            if (num2 != -1)
                                str2 = string.Format("{0}_{1}", str2, num2);
                        }

                        strContent.Append(GetVar(str2));
                    }
                }
            }

            if (flag)
                cTable.RemoveAt(cTable.Count - 1);

            return strContent.ToString();
        }

        public static void SetBlock(string strLab, int intNums)
        {
            if (_BlockCache.ContainsKey(strLab))
                _BlockCache[strLab] = intNums;
            else
                _BlockCache.Add(strLab, intNums);
        }

        public static void SetElect(string strLab, bool bolVal)
        {
            if (_ElectCache.ContainsKey(strLab))
                _ElectCache[strLab] = bolVal;
            else
                _ElectCache.Add(strLab, bolVal);
        }

        public static void SetLabel(string strLab, string strVal)
        {
            if (_LabelCache.ContainsKey(strLab))
                _LabelCache[strLab] = strVal;
            else
                _LabelCache.Add(strLab, strVal);
        }

        public static string SkinName
        {
            set
            {
                _SkinName = value;
            }
        }
    }
}